#include "./windowcontainer.h"
#include "ui/winview.h"
#include "ui/webpage.h"
#include "utils/strutils.h"

using namespace MiniUI;
using namespace MiniUI::Type;

static HCURSOR s_hCursors[CURSOR_COUNT] = {
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_IBEAM)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_CROSS)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_UPARROW)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZE)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_ICON)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEALL)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)), 
    LoadCursor(NULL, MAKEINTRESOURCE(IDC_HELP))
};

WindowContainer::WindowContainer()
: m_bMouseEnter(false)
, m_bTrackingMouse(FALSE)
, m_hCursor(NULL)
, m_szMax(-1, -1)
, m_szMin(-1, -1)
{
    m_rcUpdate.SetRectEmpty();
}

WindowContainer::~WindowContainer()
{
}

bool WindowContainer::CreateContainer(const MiniRect &rect)
{
    DWORD dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_MINIMIZEBOX;
    DWORD dwExStyle = WS_EX_OVERLAPPEDWINDOW | WS_EX_LAYERED/* | WS_EX_TOOLWINDOW*/;
    RECT rcWin = {rect.left, rect.top, rect.right, rect.bottom};

    HWND hWnd = Create(nullptr, &rcWin, nullptr, dwStyle, dwExStyle);
    SetWindowPos(nullptr, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
    return true;
}

void WindowContainer::DestroyContainer()
{
    DestroyWindow();
}

void* WindowContainer::GetHost()
{
    return m_hWnd;
}

#pragma warning(disable:4748)  
void WindowContainer::SetCaption(const char* szCaption)
{
    if (szCaption)
    {
        std::wstring wstr;
        Unicode::UTF8Decode(szCaption, wstr);
        SetWindowText(wstr.c_str());
    }
}
#pragma warning(default:4748)

void WindowContainer::SetBorder(const MiniRect& border)
{
    m_border = border;
}

void WindowContainer::SetMaxSize(const MiniSize& size)
{
    if (m_szMax != size)
    {
        m_szMax = size;
        if (IsWindow())
        {
            CRect rc(0, 0, 0, 0);
            GetWindowRect(&rc);
            MiniSize szWin(rc.Width(), rc.Height());
            MiniSize szNew = szWin;
            if (m_szMax.cx >= 0 && szWin.cx > m_szMax.cx)
            {
                szNew.cx = m_szMax.cx;
            }
            if (m_szMax.cy >= 0 && szWin.cy > m_szMax.cy)
            {
                szNew.cy = m_szMax.cy;
            }
            if (szWin != szNew)
            {
                uint flag = SWP_NOZORDER | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING;
                SetWindowPos(nullptr, 0, 0, szNew.cx, szNew.cy, flag);
            }
        }
    }
}

void WindowContainer::SetMinSize(const MiniSize& size)
{
    if (m_szMin != size)
    {
        m_szMin = size;
        if (IsWindow())
        {
            CRect rc(0, 0, 0, 0);
            GetWindowRect(&rc);
            MiniSize szWin(rc.Width(), rc.Height());
            MiniSize szNew = szWin;
            if (m_szMin.cx >= 0 && szWin.cx < m_szMin.cx)
            {
                szNew.cx = m_szMin.cx;
            }
            if (m_szMin.cy >= 0 && szWin.cy < m_szMin.cy)
            {
                szNew.cy = m_szMin.cy;
            }
            if (szWin != szNew)
            {
                uint flag = SWP_NOZORDER | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING;
                SetWindowPos(nullptr, 0, 0, szNew.cx, szNew.cy, flag);
            }
        }
    }
}

void WindowContainer::SetTopMost(bool bTopMost)
{
    HWND hWndInsertAfter = bTopMost ? HWND_TOPMOST : HWND_NOTOPMOST;
    SetWindowPos(hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}

bool WindowContainer::IsTopMost()
{
    DWORD dwExStyle = GetExStyle();
    return (dwExStyle & WS_EX_TOPMOST) != 0;
}

void WindowContainer::SetForegroundWindow()
{
    ::SetForegroundWindow(m_hWnd);
}

void WindowContainer::GetCursorPos(MiniPoint& pt)
{
    POINT ptCursor = {0};
    ::GetCursorPos(&ptCursor);
    pt.SetPoint(ptCursor.x, ptCursor.y);
}

void WindowContainer::SetCursor(CursorType cursor, void* customCursor)
{
    if (cursor == CT_NONE)
    {
        m_hCursor = NULL;
        ::SetCursor(s_hCursors[(int)CT_ARROW]);
    }
    else
    {
        if (cursor == CT_CUSTOM)
        {
            m_hCursor = (HCURSOR)customCursor;
        }
        else
        {
            m_hCursor = s_hCursors[(int)cursor];
        }
        ::SetCursor(m_hCursor);
    }
}

int WindowContainer::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    return 0;
}

void WindowContainer::OnDestroy()
{
    Bind(nullptr);
}

#pragma warning(disable:4748)
void WindowContainer::OnPaint(CDCHandle dc)
{
    CPaintDC dcPaint(m_hWnd);
    MiniRect rcClient;
    GetRect(rcClient);
    rcClient.MoveToXY(0, 0);
    m_rcUpdate.IntersectRect(m_rcUpdate, rcClient);
    if (!m_rcUpdate.IsRectEmpty())
    {
        m_graphics.Clear();
        m_graphics.SetRectClip(m_rcUpdate, false);
        m_pWinView->RenderTo(m_graphics, m_rcUpdate, 0xFF);
        lpvoid pBytes = m_pBitmap->LockBits(m_rcUpdate);
        m_dib.CopyBits(pBytes, m_rcUpdate);
        //copy bitmap
        //MiniSize szBitmap;
        //m_pBitmap->GetBitmapSize(szBitmap);
        //byte* pBytes = (byte*)m_pBitmap->LockBits(m_rcUpdate);
        //for (int i = 0; i < m_rcUpdate.Height(); ++i)
        //{
        //    MiniARGB* pSrc = (MiniARGB*)(pBytes + i * m_pBitmap->GetWidthBytes());
        //    MiniARGB* pDst = (MiniARGB*)m_dib.GetData() + (i + m_rcUpdate.top) * szBitmap.cx + m_rcUpdate.left;
        //    memcpy(pDst, pSrc, sizeof(MiniARGB) * m_rcUpdate.Width());
        //}
        RECT rc = {m_rcUpdate.left, m_rcUpdate.top, m_rcUpdate.right, m_rcUpdate.bottom};
        m_updateWindow.Update(m_hWnd, 0, m_dib, &rc, 0xFF);
    }
    m_rcUpdate.SetRectEmpty();
}
#pragma warning(default:4748)

BOOL WindowContainer::OnEraseBkgnd(CDCHandle dc)
{
    return TRUE;
}

void WindowContainer::OnSize(UINT nType, CSize size)
{
    if (m_pWinView)
    {
        m_pWinView->SetSize(MiniSize(size.cx, size.cy));
    }

    m_dib.Rebuild(size.cx, size.cy);
    m_pBitmap->Rebuild(MiniSize(size.cx, size.cy), m_dib.GetData());
    m_graphics.Rebuild(m_pBitmap);
    m_rcUpdate.SetRect(0, 0, size.cx, size.cy);
    InvalidateRect(nullptr);
}

void WindowContainer::OnMove(CPoint ptPos)
{
    if (m_pWinView)
    {
        m_pWinView->SetPos(MiniPoint(ptPos.x, ptPos.y));
    }
}

void WindowContainer::OnMouseMove(UINT nFlags, CPoint point)
{
    if (!m_bTrackingMouse)
    {
        TRACKMOUSEEVENT trackMouse = {0};
        trackMouse.cbSize = sizeof(trackMouse);
        trackMouse.hwndTrack = m_hWnd;
        trackMouse.dwFlags = TME_LEAVE;
        m_bTrackingMouse = TrackMouseEvent(&trackMouse);
    }

    if (!m_bMouseEnter)
    {
        DoMouseEnter();
        m_bMouseEnter = true;
    }
    bool bHandled = false;
    MiniPoint pt(point.x, point.y);
    DoMouseMove(pt, (uint)nFlags, bHandled);

    MiniRect rcWin;
    GetRect(rcWin);
    rcWin.MoveToXY(0, 0);

    if (m_border.IsRectNull())
    {
        m_hCursor = NULL;
        return;
    }

    MiniRect rcTop(rcWin.left, rcWin.top, rcWin.right, rcWin.top + m_border.top);
    MiniRect rcBottom(rcWin.left, rcWin.bottom - m_border.bottom, rcWin.right, rcWin.bottom);
    MiniRect rcLeft(rcWin.left, rcWin.top, rcWin.left + m_border.left, rcWin.bottom);
    MiniRect rcRight(rcWin.right - m_border.right, rcWin.top, rcWin.right, rcWin.bottom);

    if (rcTop.PtInRect(pt))
    {
        if (rcLeft.PtInRect(pt))
        {
            m_hCursor = s_hCursors[(int)CT_SIZENWSE];
        }
        else if (rcRight.PtInRect(pt))
        {
            m_hCursor = s_hCursors[(int)CT_SIZENESW];
        }
        else
        {
            m_hCursor = s_hCursors[(int)CT_SIZENS];
        }
        ::SetCursor(m_hCursor);
    }
    else if (rcBottom.PtInRect(pt))
    {
        if (rcLeft.PtInRect(pt))
        {
            m_hCursor = s_hCursors[(int)CT_SIZENESW];
        }
        else if (rcRight.PtInRect(pt))
        {
            m_hCursor = s_hCursors[(int)CT_SIZENWSE];
        }
        else
        {
            m_hCursor = s_hCursors[(int)CT_SIZENS];
        }
        ::SetCursor(m_hCursor);
    }
    else if (rcLeft.PtInRect(pt) || rcRight.PtInRect(pt))
    {
        m_hCursor = s_hCursors[(int)CT_SIZEWE];
        ::SetCursor(m_hCursor);
    }
}

void WindowContainer::OnMouseLeave()
{
    m_bTrackingMouse = false;
    DoMouseLeave();
    m_bMouseEnter = false;
}

BOOL WindowContainer::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
{
    ScreenToClient(&point);
    MiniPoint pt(point.x, point.y);
    bool bHandled = false;
    DoMouseWheel(pt, (uint)nFlags, zDelta / WHEEL_DELTA, bHandled);
    return TRUE;
}

void WindowContainer::OnLButtonDown(UINT nFlags, CPoint point)
{
    if (!m_pWinView)
    {
        return;
    }
    MiniPoint pt(point.x, point.y);
    UIObject* pObjMouseDown = m_pWinView->DoHitTest(pt);
    if (pObjMouseDown)
    {
        if (GetCapture() != m_hWnd)
        {
            SetCapture();
        }
        bool bHandled = false;
        DoMouseDown(pt, MB_L, (uint)nFlags, bHandled);
        
        if (!bHandled)
        {
            ReleaseCapture();
            ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
        }
    }
    else
    {
        ReleaseCapture();

        MiniRect rcWin;
        GetRect(rcWin);
        rcWin.MoveToXY(0, 0);

        if (m_border.IsRectNull())
        {
            ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
            return;
        }

        MiniRect rcTop(rcWin.left, rcWin.top, rcWin.right, rcWin.top + m_border.top);
        MiniRect rcBottom(rcWin.left, rcWin.bottom - m_border.bottom, rcWin.right, rcWin.bottom);
        MiniRect rcLeft(rcWin.left, rcWin.top, rcWin.left + m_border.left, rcWin.bottom);
        MiniRect rcRight(rcWin.right - m_border.right, rcWin.top, rcWin.right, rcWin.bottom);

        if (rcTop.PtInRect(pt))
        {
            if (rcLeft.PtInRect(pt))
            {
                ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, 0);
            }
            else if (rcRight.PtInRect(pt))
            {
                ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, 0);
            }
            else
            {
                ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, 0);
            }
        }
        else if (rcBottom.PtInRect(pt))
        {
            if (rcLeft.PtInRect(pt))
            {
                ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, 0);
            }
            else if (rcRight.PtInRect(pt))
            {
                ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, 0);
            }
            else
            {
                ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, 0);
            }
        }
        else if (rcLeft.PtInRect(pt))
        {
            ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, 0);
        }
        else if (rcRight.PtInRect(pt))
        {
            ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, 0);
        }
        else
        {
            ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
        }
    }
}

void WindowContainer::OnLButtonUp(UINT nFlags, CPoint point)
{
    if (GetCapture() == m_hWnd)
    {
        ReleaseCapture();
    }

    MiniPoint pt(point.x, point.y);
    bool bHandled = false;
    DoMouseUp(pt, MB_L, (uint)nFlags, bHandled);
    DoClick(pt, MB_L, (uint)nFlags, bHandled);
}

void WindowContainer::OnRButtonDown(UINT nFlags, CPoint point)
{
    if (GetCapture() != m_hWnd)
    {
        SetCapture();
    }

    bool bHandled = false;
    MiniPoint pt(point.x, point.y);
    DoMouseDown(pt, MB_R, (uint)nFlags, bHandled);
}

void WindowContainer::OnRButtonUp(UINT nFlags, CPoint point)
{
    if (GetCapture() == m_hWnd)
    {
        ReleaseCapture();
    }

    MiniPoint pt(point.x, point.y);
    bool bHandled = false;
    DoMouseUp(pt, MB_R, (uint)nFlags, bHandled);
    DoClick(pt, MB_R, (uint)nFlags, bHandled);
}

void WindowContainer::OnMButtonDown(UINT nFlags, CPoint point)
{
    if (GetCapture() != m_hWnd)
    {
        SetCapture();
    }

    bool bHandled = false;
    MiniPoint pt(point.x, point.y);
    DoMouseDown(pt, MB_M, (uint)nFlags, bHandled);
}

void WindowContainer::OnMButtonUp(UINT nFlags, CPoint point)
{
    if (GetCapture() == m_hWnd)
    {
        ReleaseCapture();
    }

    MiniPoint pt(point.x, point.y);
    bool bHandled = false;
    DoMouseUp(pt, MB_M, (uint)nFlags, bHandled);
    DoClick(pt, MB_M, (uint)nFlags, bHandled);
}

void WindowContainer::OnXButtonDown(int fwButton, int nFlags, CPoint ptPos)
{
    if (GetCapture() != m_hWnd)
    {
        SetCapture();
    }

    MiniPoint pt(ptPos.x, ptPos.y);
    bool bHandled = false;
    if (fwButton = XBUTTON1)
    {
        DoMouseDown(pt, MB_X1, (uint)nFlags, bHandled);
    }
    else if (fwButton = XBUTTON2)
    {
        DoMouseDown(pt, MB_X2, (uint)nFlags, bHandled);
    }
}

void WindowContainer::OnXButtonUp(int fwButton, int dwKeys, CPoint ptPos)
{
    if (GetCapture() == m_hWnd)
    {
        ReleaseCapture();
    }

    MiniPoint pt(ptPos.x, ptPos.y);
    bool bHandled = false;
    if (fwButton = XBUTTON1)
    {
        DoMouseUp(pt, MB_X1, (uint)dwKeys, bHandled);
        DoClick(pt, MB_X1, (uint)dwKeys, bHandled);
    }
    else if (fwButton = XBUTTON2)
    {
        DoMouseUp(pt, MB_X2, (uint)dwKeys, bHandled);
        DoClick(pt, MB_X2, (uint)dwKeys, bHandled);
    }
}

LRESULT WindowContainer::OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam)
{
    if (!bCalcValidRects)
    {
        RECT* lprc = (RECT*)(lParam);
        lprc->left = 0;
        lprc->top = 0;
        lprc->right = 0;
        lprc->bottom = 0;
    }
    return 0;
}

UINT WindowContainer::OnNcHitTest(CPoint point)
{
    return HTCLIENT;
}

void WindowContainer::OnNcPaint(CRgn rgn)
{
}

BOOL WindowContainer::OnNcActivate(BOOL bActive)
{
    m_pWinView->DoWindowActivate(bActive == TRUE);
    return TRUE;
}

void WindowContainer::OnActivate(UINT uState, BOOL bMinimized, HWND hWnd)
{
	DoActivate(uState != WA_INACTIVE);
}

BOOL WindowContainer::OnSetCursor(CWindow wnd, UINT nHitTest, UINT message)
{
    if (m_hCursor)
    {
        ::SetCursor(m_hCursor);
        SetMsgHandled(TRUE);
        return TRUE;
    }
    SetMsgHandled(FALSE);
    return FALSE; 
}

void WindowContainer::OnGetMinMaxInfo(LPMINMAXINFO lpMMI)
{
    if (m_szMax.cx >= 0)
    {
        lpMMI->ptMaxTrackSize.x = m_szMax.cx;
        lpMMI->ptMaxSize.x = m_szMax.cx;
    }

    if (m_szMax.cy >= 0)
    {
        lpMMI->ptMaxTrackSize.y = m_szMax.cy;
        lpMMI->ptMaxSize.x = m_szMax.cx;
    }

    if (m_szMin.cx >= 0)
    {
        lpMMI->ptMinTrackSize.x = m_szMin.cx;
    }

    if (m_szMin.cy >= 0)
    {
        lpMMI->ptMinTrackSize.y = m_szMin.cy;
    }
}

void WindowContainer::OnClose()
{
    DoClose();
}

void WindowContainer::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
    RECT rc = {0, 0, 0, 0};
    GetWindowRect(&rc);
    MiniRect rcWin(rc.left, rc.top, rc.right, rc.bottom);
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
    MiniRect rcWorkArea(rc.left, rc.top, rc.right, rc.bottom);

    bool bChange = false;

    int x = rcWin.left;
    int y = rcWin.top;
    if (rcWin.left < rcWorkArea.left)
    {
        x =  rcWorkArea.left;
        bChange = true;
    }

    if (rcWin.top < rcWorkArea.top)
    {
        y =  rcWorkArea.top;
        bChange = true;
    }

    if (rcWin.right > rcWorkArea.right)
    {
        x =  rcWorkArea.right - rcWin.Width();
        bChange = true;
    }

    if (rcWin.bottom > rcWorkArea.bottom)
    {
        y =  rcWorkArea.bottom - rcWin.Height();
        bChange = true;
    }

    if (bChange)
    {
        SetWindowPos(NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOSENDCHANGING);
    }
}

void WindowContainer::OnEnterSizeMove()
{
    DoFireEvent(OnNotifyEventFunc, OnDragStart, (this));
    SetMsgHandled(FALSE);
}

void WindowContainer::OnExitSizeMove()
{
    DoFireEvent(OnNotifyEventFunc, OnDragEnd, (this));
    SetMsgHandled(FALSE);
}

LRESULT WindowContainer::OnInputMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    LRESULT lRes = 0;
    //if (m_pWinView)
    //{
    //    UIObject* pObj = m_pWinView->GetFocusObject();
    //    if (pObj && pObj->CheckType(WebPage::GetTypeName()) && pObj->CheckEnable() && pObj->CheckVisible())
    //    {
    //        WebPage* pWebPage = static_cast<WebPage*>(pObj);
    //        bHandled = TRUE;
    //        HRESULT hr = pWebPage->SendMessage(uMsg, wParam, lParam);
    //        if (hr == S_OK)
    //        {
    //            return lRes;
    //        }
    //    }
    //}
    bHandled = FALSE;
    return lRes;
}

void WindowContainer::Update(const MiniRect& rect)
{
    m_rcUpdate.UnionRect(m_rcUpdate, rect);
    RECT rc = {rect.left, rect.top, rect.right, rect.bottom};
    InvalidateRect(&rc);
}

void WindowContainer::Hide()
{
    ShowWindow(SW_HIDE);
}

void WindowContainer::Show()
{
    ShowWindow(SW_SHOW);
    InvalidateRect(nullptr);
    UpdateWindow();
}

void WindowContainer::SetRect(const MiniRect& rect)
{
    if (IsWindow())
    {
        SetWindowPos(nullptr, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
    }
}

void WindowContainer::GetRect(MiniRect& rect) const
{
    if (IsWindow())
    {
        CRect rcWin;
        GetWindowRect(&rcWin);
        rect.SetRect(rcWin.left, rcWin.top, rcWin.right, rcWin.bottom);
    }
}

void WindowContainer::SetPos(const MiniPoint& pt)
{
    if (IsWindow())
    {
        SetWindowPos(nullptr, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
    }
}

void WindowContainer::GetPos(MiniPoint& pt) const
{
    if (IsWindow())
    {
        CRect rcWin;
        GetWindowRect(&rcWin);
        pt.SetPoint(rcWin.left, rcWin.top);
    }
}

void WindowContainer::SetSize(const MiniSize& sz)
{
    if (IsWindow())
    {
        SetWindowPos(nullptr, 0, 0, sz.cx, sz.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
    }
}

void WindowContainer::GetSize(MiniSize &sz) const
{
    if (IsWindow())
    {
        CRect rcWin;
        GetWindowRect(&rcWin);
        sz.SetSize(rcWin.Width(), rcWin.Height());
    }
}

void WindowContainer::SyncRect()
{
    if (IsWindow() && m_pWinView)
    {
        MiniRect rc;
        m_pWinView->GetRect(rc);
        SetWindowPos(nullptr, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING);
    }
}